package cc.htdf.gwc.datacompare.service.impl;

import cc.htdf.gwc.datacompare.domain.DataCompare;
import cc.htdf.gwc.datacompare.domain.PrecipTs;
import cc.htdf.gwc.datacompare.domain.response.ResponseBody;
import cc.htdf.gwc.datacompare.domain.response.ResponseCode;
import cc.htdf.gwc.datacompare.repository.PrecipScoreRepository;
import cc.htdf.gwc.datacompare.service.ForecaseDataService;
import cc.htdf.gwc.datacompare.service.ObserveDataService;
import cc.htdf.gwc.datacompare.service.PrecipScoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import whisper.common.exception.check.EmptyDataException;
import whisper.common.exception.sql.UniqueKeyException;
import whisper.common.utils.DateUtils;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Wangzy on 2017/11/2.
 */
@Service
public class PrecipScoreServiceImpl implements PrecipScoreService{

    @Autowired
    private ForecaseDataService forecaseDataService;

    @Autowired
    private ObserveDataService observeDataService;

    @Autowired
    private PrecipScoreRepository precipScoreRepository;

    private static final String[] stations = new String[]{"CD56181","CD56187","CD56188","CD56189","CD56272","CD56276","CD56281","CD56284","CD56285","CD56286","CD56288","CD56290","CD56295","CD56296"};

    @Override
    public void dataScore(String startDate) {

        /**
         * 实况数据获取
         */
        String observeStations = String.join(",", stations).replace("CD", "");
        String observeElements = "PRECIPITATION";
        String endData = "";
        try {
            endData = DateUtils.addHour(startDate, Integer.valueOf("24"), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        ;
             ResponseBody observeBody = observeDataService.observeDate(observeStations, startDate, endData, observeElements);
             List<Map<String, Object>> observeDatas = (List<Map<String, Object>>) observeBody.getData();

             if (!observeDatas.isEmpty()) {
             /**
             * 预报数据获取
             */
            String forecastStations = String.join(",", stations);
            String forecastElements = "POP1HR,QOP1HR";
            ResponseBody forecastBody = forecaseDataService.fetchChengDuForecast(forecastStations, forecastElements, startDate, endData);
            List<Map<String, Object>> forecastDatas = (List<Map<String, Object>>) forecastBody.getData();

            /**
             * 实况预报对比
             */
            if (!forecastDatas.isEmpty()) {
                List<PrecipTs> dataList = new ArrayList<>();
                List<DataCompare> tempList = new ArrayList<>();
                double paramA = 0;
                double paramB = 0;
                double paramC = 0;
                double paramD = 0;

                for(int i=0;i<observeDatas.size();i++){
                    for(int j=0;j<forecastDatas.size();j++){
                        if(("CD"+String.valueOf(observeDatas.get(i).get("SITE_ID"))).equals(forecastDatas.get(j).get("STATIONID")) && String.valueOf(observeDatas.get(i).get("OBSERVATION_DATE")).equals(forecastDatas.get(j).get("VALIDDATETIME"))){
                            if(forecastDatas.get(j).get("POP1HR")!=null && observeDatas.get(i).get("PRECIPITATION")!=null) {
                                if (Integer.parseInt(forecastDatas.get(j).get("POP1HR").toString()) <= 20 && Double.parseDouble(observeDatas.get(i).get("PRECIPITATION").toString()) == 0)
                                    paramD += 1;
                                else if (Integer.parseInt(forecastDatas.get(j).get("POP1HR").toString()) <= 20 && Double.parseDouble(observeDatas.get(i).get("PRECIPITATION").toString()) > 0)
                                    paramC += 1;
                                else if (Integer.parseInt(forecastDatas.get(j).get("POP1HR").toString()) > 20 && Double.parseDouble(observeDatas.get(i).get("PRECIPITATION").toString()) == 0)
                                    paramB += 1;
                                else if (Integer.parseInt(forecastDatas.get(j).get("POP1HR").toString()) > 20 && Double.parseDouble(observeDatas.get(i).get("PRECIPITATION").toString()) > 0)
                                    paramA += 1;
                            }
                        }
                    }
                }
                //评分标准
                DecimalFormat df = new DecimalFormat("######0.00");
                String pc = String.format("%.4f", (paramA+paramD)/(paramA+paramB+paramC+paramD));
                String ts = String.format("%.4f", paramA/(paramA+paramB+paramC));
                String mar = String.format("%.4f", paramC/(paramA+paramC));
                String far = String.format("%.4f", paramB/(paramA+paramB));

                PrecipTs precipTs = new PrecipTs();
                precipTs.setModelRunDateTime(startDate);
                precipTs.setParamA(String.valueOf(paramA));
                precipTs.setParamB(String.valueOf(paramB));
                precipTs.setParamC(String.valueOf(paramC));
                precipTs.setParamD(String.valueOf(paramD));
                precipTs.setAccuracy(String.valueOf(pc));
                precipTs.setTs(String.valueOf(ts));
                precipTs.setLeak(String.valueOf(mar));
                precipTs.setEmpty(String.valueOf(far));
                dataList.add(precipTs);
                try {
                    precipScoreRepository.saveScoreData(dataList);
                } catch (Exception e) {
                    throw new UniqueKeyException(ResponseCode.STATUS_ERROR, "时间冲突[" + startDate + "]，存在该时次的对比数据！");
                }
            }
        } else {
            throw new EmptyDataException(ResponseCode.STATUS_ERROR, "实况数据为空！");
        }

    }

    @Override
    public List<Map<String, Object>> queryPrecip() {
        return precipScoreRepository.queryPrecip();
    }
}
